/*
 * @Author: fuqiming hb.fuqiming@aisino.com
 * @Date: 2024-03-09 16:19:38
 * @LastEditors: fuqiming hb.fuqiming@aisino.com
 * @LastEditTime: 2024-03-09 18:35:45
 * @Description: 
 */

export namespace FQM_1 {
  export class Module_1 {
    private value: string

    constructor(value: string) {
      this.value = value
    }

    public get() {
      return this.value
    }

    // ...
  }

  // 用实例的方式使用module_1模块
  class Module_2 {
    private value: string

    constructor(value: string) {
      const module_1 = new Module_1(value)
      this.value = module_1.get()
    }
  }

  // 如果使用以上的方式，那么一但Module_1构造函数的入参等一些跟Module_2相关的被修改，那么Module_2就会被影响
  // 这被称为强耦合
  // 注意这跟继承不同，可能Module_2只想用Module1的某些变量或方法，就会出现类似的场景


  // 下面使用依赖注入
  class Container {
    private modules: Modules

    constructor() {
      this.modules = Object.create(null)
    }

    // 注入依赖
    public inject(key: ObjectKey, module: any) {
      this.modules[key] = module
    }

    // 提供依赖
    public provide(key: ObjectKey) {
      return this.modules[key]
    }
  }

  const container = new Container()

  const ex1_module = new Module_1('fqmyysjjd')

  const ex2_module = new Module_1('fqmyysjjddx')

  // 注入
  container.inject('key1', ex1_module)
  container.inject('key2', ex2_module)

  // 使用
  class FQM {
    value1: Module_1
    value2: Module_2

    constructor() {
      this.value1 = container.provide('key1')
      this.value2 = container.provide('key1')
    }
  }

  const fqm = new FQM()

  console.log(fqm.value1.get())
  console.log(fqm.value2)

  // 如此一来就实现了解耦, Container彻底成为了一个中间的类, 作为一个容器: 无论被注入的模块类怎么改变, 都可以实现解耦, 只要对外提供的方法不变(public), 依旧可以使用
  // 这就是依赖注入. 实际上就是创造了一个中间的容器, 用于将一些模块放入, 进行管理, 需要时引入即可
}
